#include "SDL.h"
//#include "SDL_draw.h"
#include <iostream>


const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 600;
const int SCREEN_BPP = 32;

const int FRAMES_PER_SECOND = 20;

//The dot dimensions
const int DOT_WIDTH = 20;
const int DOT_HEIGHT = 20;

//The dimensions of the level
const int LEVEL_WIDTH = 1280;
const int LEVEL_HEIGHT = 960;

SDL_Rect camera = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT };

SDL_Event event;

class Dot
{
    private:
    //The X and Y offsets of the dot
    int x, y;

    //The velocity of the dot
    int xVel, yVel;

    public:
    //Initializes the variables
    Dot();

    //Takes key presses and adjusts the dot's velocity
    void handle_input();

    //Moves the dot
    void move();

    //Shows the dot on the screen
	void show(SDL_Surface*,SDL_Surface*);

    //Sets the camera over the dot
    void set_camera();
};

void aplicar_superficie(int x, int y,SDL_Surface* source,SDL_Surface* destination,SDL_Rect* clip = NULL){
    SDL_Rect offset;

    offset.x=x;
    offset.y=y;

    SDL_BlitSurface(source,clip,destination,&offset);
}


Dot::Dot()
{
    //Initialize the offsets
    x = 0;
    y = 0;

    //Initialize the velocity
    xVel = 0;
    yVel = 0;
}

void Dot::handle_input()
{
    //If a key was pressed
    if( event.type == SDL_KEYDOWN )
    {
        //Adjust the velocity
        switch( event.key.keysym.sym )
        {
            case SDLK_UP: yVel -= DOT_HEIGHT / 2; break;
            case SDLK_DOWN: yVel += DOT_HEIGHT / 2; break;
            case SDLK_LEFT: xVel -= DOT_WIDTH / 2; break;
            case SDLK_RIGHT: xVel += DOT_WIDTH / 2; break;
        }
    }
    //If a key was released
    else if( event.type == SDL_KEYUP )
    {
        //Adjust the velocity
        switch( event.key.keysym.sym )
        {
            case SDLK_UP: yVel += DOT_HEIGHT / 2; break;
            case SDLK_DOWN: yVel -= DOT_HEIGHT / 2; break;
            case SDLK_LEFT: xVel += DOT_WIDTH / 2; break;
            case SDLK_RIGHT: xVel -= DOT_WIDTH / 2; break;
        }
    }
}

void Dot::move()
{
    //Move the dot left or right
    x += xVel;

    //If the dot went too far to the left or right
    if( ( x < 0 ) || ( x + DOT_WIDTH > LEVEL_WIDTH ) )
    {
        //move back
        x -= xVel;
    }

    //Move the dot up or down
    y += yVel;

    //If the dot went too far up or down
    if( ( y < 0 ) || ( y + DOT_HEIGHT > LEVEL_HEIGHT ) )
    {
        //move back
        y -= yVel;
    }
}

void Dot::show(SDL_Surface* dot,SDL_Surface* screen)
{
    //Show the dot
	aplicar_superficie( x - camera.x, y - camera.y, dot, screen );
}

void Dot::set_camera()
{
    //Center the camera over the dot
    camera.x = ( x + DOT_WIDTH / 2 ) - SCREEN_WIDTH / 2;
    camera.y = ( y + DOT_HEIGHT / 2 ) - SCREEN_HEIGHT / 2;

    //Keep the camera in bounds.
    if( camera.x < 0 )
    {
        camera.x = 0;
    }
    if( camera.y < 0 )
    {
        camera.y = 0;
    }
    if( camera.x > LEVEL_WIDTH - camera.w )
    {
        camera.x = LEVEL_WIDTH - camera.w;
    }
    if( camera.y > LEVEL_HEIGHT - camera.h )
    {
        camera.y = LEVEL_HEIGHT - camera.h;
    }
}


SDL_Surface* loadImagen(const char* imagen){

    SDL_Surface* imagen1=NULL;
    SDL_Surface* imagenOptimizada=NULL;

    imagen1=SDL_LoadBMP(imagen);

    if (imagen1!=NULL){
        imagenOptimizada=SDL_DisplayFormat(imagen1);

        SDL_FreeSurface(imagen1);
    }

    return imagenOptimizada;
}

void dibujarCalle(float x,float y,SDL_Surface* pantalla){

    SDL_Rect offset;

    offset.x=(uint16_t)x;
    offset.y=(uint16_t)y;
	//offset.h=((float)SCREEN_HEIGHT/1000)*10;
	offset.h=10;
	//offset.w=((float)SCREEN_WIDTH/1000)*100;
	offset.w=100;
   // std::<< pantalla->format->BitsPerPixel << std::endl;
    SDL_FillRect(pantalla,&offset,SDL_MapRGB(pantalla->format,0xFF,0xFF,0xA0));

}

void dibujarCalleVertical(float x,float y,SDL_Surface* pantalla){

    SDL_Rect offset;

    offset.x=(uint16_t)x;
    offset.y=(uint16_t)y;
	//offset.h=((float)SCREEN_HEIGHT/1000)*10;
	offset.h=100;
	//offset.w=((float)SCREEN_WIDTH/1000)*100;
	offset.w=10;
    //std::cout << pantalla->format->BitsPerPixel << std::endl;

    SDL_FillRect(pantalla,&offset,SDL_MapRGB(pantalla->format,0xFF,0xFF,0xA0));

}


int test01(){

    //Quit flag
    bool quit = false;

    //The offsets of the background
    int bgX = 0, bgY = 0;


    SDL_Init( SDL_INIT_EVERYTHING );
    //Quit SDL
	SDL_Surface* screen=SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_SWSURFACE|SDL_DOUBLEBUF);

    SDL_WM_SetCaption("Tanks",NULL);

    SDL_Surface* hello=loadImagen("tank.bmp");
    SDL_Surface* fondo=loadImagen("sel2.bmp");

    aplicar_superficie(0,0,fondo,screen);
    aplicar_superficie(100,0,fondo,screen);
    aplicar_superficie(0,100,fondo,screen);
    aplicar_superficie(100,100,fondo,screen);

    aplicar_superficie(0,0,hello,screen);
    while( quit == false )
    {
        //Start the frame timer

      //  fps.start();

        //While there's events to handle
        while( SDL_PollEvent( &event ) )
        {
            //If the user has Xed out the window
            if( event.type == SDL_QUIT )
            {
                //Quit the program
                quit = true;
            }
        }

        //Scroll background
        bgX -= 2;

        //If the background has gone too far

		if( bgX <= -fondo->w )
        {
            //Reset the offset
            bgX = 0;
        }

        //Show the background
        aplicar_superficie( bgX, bgY, fondo, screen );
        aplicar_superficie( bgX + fondo->w, bgY, fondo, screen );

        //Show the dot
        aplicar_superficie( 310, 230, hello, screen );

        //Update the screen
        if( SDL_Flip( screen ) == -1 )
        {
            return 1;
        }
    }


    SDL_FreeSurface(hello);
    SDL_FreeSurface(fondo);

    std::cout << "Fin\n";
    SDL_Quit();

}

int test02(){

	//The camera

	Dot myDot;

    SDL_Init( SDL_INIT_EVERYTHING );
    //Quit SDL
	SDL_Surface* screen=SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_SWSURFACE);

    SDL_WM_SetCaption("Tanks!!!",NULL);

	SDL_Surface* tank=loadImagen("tank.bmp");
    Uint32 colorkey=SDL_MapRGB(tank->format,0,0xFF,0xFF);
    SDL_SetColorKey(tank,SDL_SRCCOLORKEY,colorkey);
    
	SDL_Surface* fondo=loadImagen("sel1.bmp");
    Uint32 colorkey2=SDL_MapRGB(fondo->format,0,0xFF,0xFF);
    SDL_SetColorKey(fondo,SDL_SRCCOLORKEY,colorkey2);
	
	//imprime la coordenada en la consola
	std::cout << screen->pitch << std::endl;
	Uint8* p = (Uint8*)screen->pixels+ 10*screen->pitch+ 10*24;
	std::cout << (Uint8)screen->pixels << std::endl;

	    aplicar_superficie(0,0,fondo,screen);

    aplicar_superficie(240,190,tank,screen);

	dibujarCalle(50.0,26.23,screen);
	
	bool quit=false;

    while( quit == false )
    {
        //Start the frame timer
		//fps.start();

        //While there's events to handle
        while( SDL_PollEvent( &event ) )
        {
            //Handle events for the dot
            myDot.handle_input();

            //If the user has Xed out the window
            if( event.type == SDL_QUIT )
            {
                //Quit the program
                quit = true;
            }
        }

        //Move the dot
        myDot.move();

        //Set the camera
        myDot.set_camera();

        //Show the background
        aplicar_superficie( 0, 0, fondo, screen, &camera );
		
		std::cout << camera.x << "\t" << camera.y << "\n";
		
		if ((camera.x<=40) && (camera.y<=40))
			//Draw_FillCircle(screen,42-camera.x,25-camera.y,8,0xf0);
		aplicar_superficie(35-camera.x,17.5-camera.y,tank,screen);
		aplicar_superficie(150-camera.x,17.5-camera.y,tank,screen);
		aplicar_superficie(35-camera.x,132.5-camera.y,tank,screen);
		dibujarCalleVertical(37.5-camera.x,32.5-camera.y,screen);
		dibujarCalle(50-camera.x,20-camera.y,screen);
		
        //Show the dot on the screen
		myDot.show(tank,screen);

        //Update the screen
        if( SDL_Flip( screen ) == -1 )
        {
            return 1;
        }

        //Cap the frame rate
  /*      if( fps.get_ticks() < 1000 / 20 )
        {
            SDL_Delay( ( 1000 / 20 )  );
        }*/
    }

    SDL_FreeSurface(tank);
    SDL_FreeSurface(fondo);

    std::cout << "FIN\n";
    SDL_Quit();

}

int main( int argc, char* args[] ) {
    char pepe;
    std::cout << "ingrese una tecla" << std::endl;
    std::cin >> pepe;

	//Efecto de fondo desplazandose
	//test01();

	//muestra un fondo y el tanque. Tanque se desplaza
	test02();


return 0;
}
